<script setup lang="ts">
import { computed, ref, useTemplateRef } from 'vue';
import { useStory, useTypewriter } from '../../composables';
import StarBackgroundContainer from './components/star-background-container/index.vue';
import { EVENTS, GameKernel } from '../../game';
import { STORY_STATE } from '../../game/systems/story/story-engine';

const contentRef = useTemplateRef('contentRef');

const { state: storyState } = useStory();

const currentLines = ref<string[]>([]);
const {
  displayedText,
  isRunning: isTextAnimationRunning,
  start: startTextAnimation,
  skip: skipTextAnimation,
} = useTypewriter(currentLines, {
  charInterval: 30,
  linePause: 100,
  autoStart: true,
  onFinish() {
    if (
      storyState.value.currentItem?.type === 'narrator' ||
      storyState.value.currentItem?.type === 'dialog'
    ) {
      GameKernel.inst.bus.emit(EVENTS.STORY_NOTIFY_UI_READY);
    }
  },
  onChar() {
    if (!contentRef.value) return;
    contentRef.value.scrollTop = contentRef.value.scrollHeight;
  },
});

const choices = computed(() => {
  const currentItem = storyState.value.currentItem;
  if (!currentItem || currentItem.type !== 'choice') return [];
  return currentItem.choices;
});

const canContinue = computed(() => {
  return (
    storyState.value.currentState === STORY_STATE.WAITING_FOR_UI ||
    storyState.value.currentState === STORY_STATE.PLAYING
  );
});

function onEndClick() {
  GameKernel.inst.bus.emit(EVENTS.STORY_STOP);
  if (storyState.value.hasAchievedAllSuccess) {
  } else {
  }
}

function onContinueClick() {
  const currentItem = storyState.value.currentItem;
  if (currentItem && currentItem.type === 'dialog') {
    GameKernel.inst.bus.emit(EVENTS.STORY_NOTIFY_UI_READY);
  } else {
    skipTextAnimation();
  }
}

function onChoiceClick(index: number) {
  GameKernel.inst.bus.emit(EVENTS.STORY_MAKE_CHOICE, index);
}

GameKernel.inst.bus.on(EVENTS.STORY_STATE_UPDATE, () => {
  let strList: string[] = [];
  const currentItem = storyState.value.currentItem;
  if (currentItem) {
    strList = currentItem.text;
  }
  currentLines.value = strList;
  startTextAnimation();
});
</script>

<template>
  <div
    v-if="storyState.currentState !== STORY_STATE.IDLE"
    class="story-player absolute w-screen h-screen z-10 bg-container-background text-primary-text flex flex-col"
  >
    <star-background-container :is-absolute="false">
      <div
        ref="contentRef"
        class="flex-1 h-full overflow-auto p-2 flex flex-col"
      >
        <div class="mt-auto">
          <div v-for="(item, index) in storyState.history" :key="index">
            <pre v-if="item.type === 'narrator'">{{
              item.displayText?.join('\n')
            }}</pre>
            <div v-if="item.type === 'choice'">
              <pre>{{ item.displayText?.join('\n') }}</pre>
              <pre class="text-blue-400">{{ item.choice?.text }}</pre>
            </div>
            <div v-if="item.type === 'dialog'">
              <div>{{ item.speaker }}:</div>
              <pre>{{ item.displayText?.join('\n') }}</pre>
            </div>
          </div>
          <div
            v-if="
              storyState.currentItem && storyState.currentItem.type === 'dialog'
            "
          >
            {{ storyState.currentItem.name }}:
          </div>
          <pre>{{ displayedText || currentLines.join('\n') }}</pre>
        </div>
      </div>
      <div v-if="choices.length" class="flex flex-col px-2 gap-2">
        <div v-for="(btn, index) in choices" :key="index" class="text-right">
          <a-button type="primary" @click="onChoiceClick(index)">
            {{ btn.text }}
          </a-button>
        </div>
      </div>
      <div v-else class="flex-none flex items-center justify-end gap-2 p-2">
        <a-button
          v-if="
            storyState.currentState === STORY_STATE.WAITING_FOR_UI ||
            storyState.currentState === STORY_STATE.PLAYING
          "
          :disabled="
            !canContinue ||
            (isTextAnimationRunning &&
              storyState.currentItem?.type === 'dialog')
          "
          @click="onContinueClick"
        >
          继续
        </a-button>
        <a-button v-else @click="onEndClick">结束</a-button>
      </div>
    </star-background-container>
  </div>
</template>

<style scoped>
.story-player pre {
  margin: 0;
  font-family: 'Consolas', 'Courier New', monospace;
  white-space: pre-wrap;
  word-break: break-all;
  line-height: 1.6;
}
</style>
